package com.fine.hair.comm.utils;

import com.fine.hair.comm.exception.BusinessException;
import com.google.common.collect.Lists;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author junelee
 * @date 2020/5/21 下午2:02
 */
public class Utils {

    private static final String allChar = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

    /**
     * 元转分，确保price保留两位有效数字
     *
     * @return
     */
    public static int changeY2F(double price) {
        DecimalFormat df = new DecimalFormat("#.00");
        price = Double.parseDouble(df.format(price));
        return (int) (price * 100);
    }

    /**
     * 分转元，转换为bigDecimal在toString
     *
     * @return
     */
    public static String changeF2Y(int price) {
        return BigDecimal.valueOf((long) price).divide(new BigDecimal(100)).toString();
    }

    /**
     * 判断是否在允许范围内的后缀
     *
     * @param ext
     * @return
     */
    public static boolean checkExt(String allowExt, String ext) {
        if (ext.length() == 0) {
            return false;
        }
        String[] params = allowExt.split("\\|");
        for (int i = 0; i < params.length; i++) {
            if (params[i].equals(ext)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 文件重命名
     * 生成16位得随机字符串
     *
     * @param myFileName 文件名
     * @return
     */
    public static String generateString(String myFileName) {
        // 截取图片后缀
        //String imgstr = myFileName.substring(myFileName.lastIndexOf("\\."));
        String imgstr = myFileName.substring(myFileName.lastIndexOf("."));
        StringBuffer sb = new StringBuffer();
        Random random = new Random();
        for (int i = 1; i <= 16; i++) {
            sb.append(allChar.charAt(random.nextInt(allChar.length())));
        }
        return sb.toString() + imgstr;
    }

    /**
     * 获取请求basePath
     */
    public static String getBasePath(HttpServletRequest request) {
        StringBuffer basePath = new StringBuffer();
        String scheme = request.getScheme();
        String domain = request.getServerName();
        int port = request.getServerPort();
        basePath.append(scheme);
        basePath.append("://");
        basePath.append(domain);
        if ("http".equalsIgnoreCase(scheme) && 80 != port) {
            basePath.append(":").append(port);
        } else if ("https".equalsIgnoreCase(scheme) && port != 443) {
            basePath.append(":").append(port);
        }
        return basePath.toString();
    }


    public static String utf8Togb2312(String str) {

        StringBuffer sb = new StringBuffer();

        for (int i = 0; i < str.length(); i++) {

            char c = str.charAt(i);

            switch (c) {

                case '+':

                    sb.append(' ');

                    break;

                case '%':

                    try {

                        sb.append((char) Integer.parseInt(

                                str.substring(i + 1, i + 3), 16));

                    } catch (NumberFormatException e) {

                        throw new IllegalArgumentException();

                    }

                    i += 2;

                    break;

                default:

                    sb.append(c);

                    break;

            }

        }

        String result = sb.toString();

        String res = null;

        try {

            byte[] inputBytes = result.getBytes("8859_1");

            res = new String(inputBytes, "UTF-8");

        } catch (Exception e) {
        }

        return res;

    }

// 将 GB2312 编码格式的字符串转换为 UTF-8 格式的字符串：

    public static String gb2312ToUtf8(String str) {

        String urlEncode = "";

        try {

            urlEncode = URLEncoder.encode(str, "UTF-8");

        } catch (UnsupportedEncodingException e) {

            e.printStackTrace();

        }

        return urlEncode;

    }

    public static String getIp(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    /**
     * 每隔几天一个日期
     *
     * @return
     */
    public static List<Date> getExecuteDateByDate(int orderCount, int day, Date startDate) {
        int thisDay = day;
        ArrayList<Date> dateList = Lists.newArrayList();
        for (int i = 0; i < orderCount; i++) {
            if (i == 0) {
                dateList.add(startDate);
            } else {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(startDate);
                //+后 -前
                calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + thisDay);
                dateList.add(calendar.getTime());
                thisDay += day;
            }
        }
        return dateList;
    }

    /**
     * 日期相减得到天
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static int getDayDiff(String startDate, String endDate) {
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(stringTodate(startDate, "yyyy-MM-dd"));
        c2.setTime(stringTodate(endDate, "yyyy-MM-dd"));

        int day1 = c1.get(Calendar.DAY_OF_YEAR);
        int day2 = c2.get(Calendar.DAY_OF_YEAR);

        int year1 = c1.get(Calendar.YEAR);
        int year2 = c2.get(Calendar.YEAR);
        if (year1 != year2)   //同一年
        {
            int timeDistance = 0;
            for (int i = year1; i < year2; i++) {
                if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0)    //闰年
                {
                    timeDistance += 366;
                } else    //不是闰年
                {
                    timeDistance += 365;
                }
            }
            return timeDistance + (day2 - day1);
        } else    //不同年
        {
            return day2 - day1;
        }
    }

    /**
     * 获取两个日期相差的月数
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static int getMonthDiff(String startDate, String endDate) {
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(stringTodate(startDate, "yyyy-MM"));
        c2.setTime(stringTodate(endDate, "yyyy-MM"));
        int year1 = c1.get(Calendar.YEAR);
        int year2 = c2.get(Calendar.YEAR);
        int month1 = c1.get(Calendar.MONTH);
        int month2 = c2.get(Calendar.MONTH);
        int day1 = c1.get(Calendar.DAY_OF_MONTH);
        int day2 = c2.get(Calendar.DAY_OF_MONTH);
        // 获取年的差值
        int yearInterval = year1 - year2;
        // 如果 d1的 月-日 小于 d2的 月-日 那么 yearInterval-- 这样就得到了相差的年数
        if (month1 < month2 || month1 == month2 && day1 < day2) {
            yearInterval--;
        }
        // 获取月数差值
        int monthInterval = (month1 + 12) - month2;
        if (day1 < day2) {
            monthInterval--;
        }
        monthInterval %= 12;
        int monthsDiff = Math.abs(yearInterval * 12 + monthInterval);
        return monthsDiff;

    }

    /**
     * 计算两个日期相差年数
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static int getYearDiff(String startDate, String endDate) {
        Calendar calBegin = Calendar.getInstance(); //获取日历实例
        Calendar calEnd = Calendar.getInstance();
        calBegin.setTime(stringTodate(startDate, "yyyy"));
        calEnd.setTime(stringTodate(endDate, "yyyy"));
        return calEnd.get(Calendar.YEAR) - calBegin.get(Calendar.YEAR);
    }


    /**
     * 字符串按照指定格式转化为日期
     *
     * @param dateStr
     * @param formatStr
     * @return
     */
    public static Date stringTodate(String dateStr, String formatStr) {
        // 如果时间为空则默认当前时间
        Date date;
        SimpleDateFormat format = new SimpleDateFormat(formatStr);
        if (dateStr != null && !dateStr.equals("")) {
            try {
                date = format.parse(dateStr);
            } catch (ParseException e) {
                throw new BusinessException("日期格式转换错误");
            }
        } else {
            String timeTwo = format.format(new Date());
            try {
                date = format.parse(timeTwo);
            } catch (ParseException e) {
                throw new BusinessException("日期格式转换错误");
            }
        }
        return date;
    }

    /**
     * 获取两个日期之间所有的月份集合
     *
     * @param startTime
     * @param endTime
     * @return：YYYY-MM
     */
    public static List<String> getDayList(String startTime, String endTime) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        // 声明保存日期集合
        List<String> list = new ArrayList<String>();
        try {
            // 转化成日期类型
            Date startDate = sdf.parse(startTime);
            Date endDate = sdf.parse(endTime);

            //用Calendar 进行日期比较判断
            Calendar calendar = Calendar.getInstance();
            while (startDate.getTime() <= endDate.getTime()) {
                // 把日期添加到集合
                list.add(sdf.format(startDate));
                // 设置日期
                calendar.setTime(startDate);
                //把日期增加一天
                calendar.add(Calendar.DATE, 1);
                // 获取增加后的日期
                startDate = calendar.getTime();
            }
        } catch (ParseException e) {
            throw new BusinessException("日期格式转换错误");
        }
        return list;
    }

    /**
     * 获取两个日期之间所有的月份集合
     *
     * @param startTime
     * @param endTime
     * @return：YYYY-MM
     */
    public static List<String> getMonthList(String startTime, String endTime) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        // 声明保存日期集合
        List<String> list = new ArrayList<String>();
        try {
            // 转化成日期类型
            Date startDate = sdf.parse(startTime);
            Date endDate = sdf.parse(endTime);

            //用Calendar 进行日期比较判断
            Calendar calendar = Calendar.getInstance();
            while (startDate.getTime() <= endDate.getTime()) {
                // 把日期添加到集合
                list.add(sdf.format(startDate));
                // 设置日期
                calendar.setTime(startDate);
                //把日期增加一天
                calendar.add(Calendar.MONTH, 1);
                // 获取增加后的日期
                startDate = calendar.getTime();
            }
        } catch (ParseException e) {
            throw new BusinessException("日期格式转换错误");
        }
        return list;
    }


    /**
     * 获取两个日期之间所有的月份集合
     *
     * @param startTime
     * @param endTime
     * @return：YYYY-MM
     */
    public static List<String> getYearList(String startTime, String endTime) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
        // 声明保存日期集合
        List<String> list = new ArrayList<String>();
        try {
            // 转化成日期类型
            Date startDate = sdf.parse(startTime);
            Date endDate = sdf.parse(endTime);

            //用Calendar 进行日期比较判断
            Calendar calendar = Calendar.getInstance();
            while (startDate.getTime() <= endDate.getTime()) {
                // 把日期添加到集合
                list.add(sdf.format(startDate));
                // 设置日期
                calendar.setTime(startDate);
                //把日期增加一天
                calendar.add(Calendar.YEAR, 1);
                // 获取增加后的日期
                startDate = calendar.getTime();
            }
        } catch (ParseException e) {
            throw new BusinessException("日期格式转换错误");
        }
        return list;
    }




    public static Date beforeDay(Date date, int count) {
        Calendar cal = new GregorianCalendar();
        cal.setTime(date);
        cal.set(Calendar.DATE, cal.get(Calendar.DATE) - count);
        date = cal.getTime();
        return date;
    }

    /**
     * 格式化指定日期
     *
     * @param pattern
     * @return
     */
    public static String format(Date date, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(date);
    }

}
